package org.docmanagement.actions;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.docmanagement.commons.service.ServiceException;
import org.docmanagement.commons.struts.CommonAction;
import org.docmanagement.data.Book;
import org.docmanagement.data.Category;
import org.docmanagement.data.Element;
import org.docmanagement.data.File;
import org.docmanagement.data.Keyword;
import org.docmanagement.data.Link;
import org.docmanagement.forms.CategoryForm;
import org.docmanagement.forms.ElementForm;
import org.docmanagement.forms.IdForm;
import org.docmanagement.services.CategoryException;
import org.docmanagement.services.ConfigurationException;
import org.docmanagement.services.KeywordException;
import org.docmanagement.services.RepositoryException;

/**
 * Created on 27 oct. 2004
 * @author eveno
 */
public class ElementAction extends CommonAction
{
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#createMethodMap()
     */
    protected void createMethodMap()
    {
        methodMap = new HashMap<String, String>();
        methodMap.put("Lister", "list");
        methodMap.put("Ajouter", "add");
        methodMap.put("Modifier", "get");
        methodMap.put("Sauver", "update");
        methodMap.put("Supprimer", "delete");
        methodMap.put("PrepareAdd", "getRessources");
        methodMap.put("PrepareRemove", "get");
    }
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#list(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception
    {
        IdForm idForm = (IdForm) form;
        if (idForm.getId() == null)
        {
            request.getSession(true).removeAttribute(CATEGORY_KEY);
        	if (request.getAttribute(CATEGORY_KEY) != null)
        	{
        	    CategoryForm categoryForm = (CategoryForm) request.getAttribute(CATEGORY_KEY);
        	    idForm.setId(categoryForm.getId());
        	}
        }
        listElements(request, idForm.getId(), false);
        return mapping.findForward(SHOW);
    }
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#list(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // Do the work to add the new element
        ElementForm elementForm = (ElementForm) form;
        Element e = toElement(elementForm);
        getElementService().add(e);

        listElements(request, null, true);

        return mapping.findForward(SHOW);
    }
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#list(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward get(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception
    {
        IdForm idForm = (IdForm) form;
        log.info("Retreiving element for id: "+idForm.getId());
        Element e = (Element) getElementService().findById(idForm.getId());
        
        addElement(request, e);
        addCategoryList(request);
        addKeywordList(request);

        if ("Modifier".equals(getActionName(mapping, request)))
            return mapping.findForward(EDIT);
        return mapping.findForward(REMOVE);
    }
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#list(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward update(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception
    {
        ElementForm elementForm = (ElementForm) form;
        Element e = (Element) getElementService().findById(elementForm.getId());
        updateElement(e, elementForm);
        log.info("Updating element with id: "+elementForm.getId());

        if (elementForm.getType() == FILE_TYPE && elementForm.getMainCategoryId() != null)
        {
            Category mainCategory = (Category) getCategoryService().findById(elementForm.getMainCategoryId());
            log.debug("Updating main category with "+mainCategory);
            ((File) e).setMainCategory(mainCategory);
            getRepositoryService().updateFile((File) e);
        }

        getElementService().update(e);
        
        addElement(request, e);
        addCategoryList(request);
        addKeywordList(request);

        listElements(request, null, true);
        
        return mapping.findForward(SHOW);
    }
    /**
     * @see org.docmanagement.commons.struts.BaseDispatchAction#list(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception
    {
        IdForm idForm = (IdForm) form;
        Element e = (Element) getElementService().findById(idForm.getId());
        if (e.getType() == FILE_TYPE)
            getRepositoryService().removeFile((File) e);
        log.info("Removing element with id: "+idForm.getId());
        getElementService().removeById(idForm.getId());

        listElements(request, null, true);

        return mapping.findForward(SHOW);
    }
    /**
     * @param request
     * @param e
     * @throws ConfigurationException
     */
    private void addElement(HttpServletRequest request, Element e) throws ConfigurationException
    {
        ElementForm form = fromElement(e);
        request.setAttribute(ELEMENT_KEY, form);        
    }
    /**
     * @param elementForm
     * @return
     * @throws RepositoryException
     * @throws ConfigurationException
     */
    private Element toElement(ElementForm elementForm) throws ServiceException
    {
        Element e = null;
        if (elementForm.getType() == LINK_TYPE)
        {
            e = new Link(elementForm.getUrl());
        }
        if (elementForm.getType() == BOOK_TYPE)
        {
            e = new Book();
        }
        if (elementForm.getType() == FILE_TYPE)
        {
            e = new File(elementForm.getFilepath());
            if (elementForm.getMainCategoryId() != null)
            {
	            Category mainCategory = (Category) getCategoryService().findById(elementForm.getMainCategoryId());
	            ((File) e).setMainCategory(mainCategory);
            }
            getRepositoryService().addFile((File) e);
        }
        updateElement(e, elementForm);
        return e;
    }
    /**
     * @param e
     * @param elementForm
     * @throws CategoryException
     * @throws KeywordException
     * @throws RepositoryException
     */
    private void updateElement(Element e, ElementForm elementForm) throws ServiceException
    {
        e.setTitle(elementForm.getTitle());
        e.setDescription(elementForm.getDescription());
        if (elementForm.getCategoryIds().length != 0)
            e.setCategories( getCategoryService().findAll(elementForm.getCategoryIds()) );
        if (elementForm.getKeywordIds().length != 0)
        {
            List<Keyword> keywords = getKeywordService().findAll(elementForm.getKeywordIds());
            e.setKeywords( keywords );
        }
        if (elementForm.isAddnewkeyword())
        {
            Keyword newKeyword = new Keyword();
            newKeyword.setName(elementForm.getNewkeyword());
            Integer id = getKeywordService().add(newKeyword);
            newKeyword.setId(id);
            if (e.getKeywords() == null)
                e.setKeywords(new LinkedList<Keyword>());
            e.getKeywords().add(newKeyword);
        }
    }
}
